package com.gitee.wsl.platform

import kotlinx.cinterop.*
import platform.Foundation.*
import platform.posix.pathconf
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.set

@OptIn(BetaInteropApi::class)
val String.nativeStr: NSString
    get() = NSString.create(string = this)

//
//object FileSystem {
//
//    private var manager = NSFileManager.defaultManager
//
//    @OptIn(ExperimentalForeignApi::class)
//    private fun getDirUrl(directory: NSSearchPathDirectory, create: Boolean = false): NSURL? {
//        memScoped {
//            val error = alloc<ObjCObjectVar<NSError?>>()
//            return manager.URLForDirectory(directory, NSUserDomainMask, null, create, error.ptr)?.standardizedURL
//        }
//    }
//
//    private fun getDirPath(directory: NSSearchPathDirectory, create: Boolean = false): Path {
//        return Path.fromUrl(getDirUrl(directory, create))
//    }
//
//    @OptIn(ExperimentalForeignApi::class)
//    private fun attributesOfFile(filePath: String): Map<String, Any?> {
//        memScoped {
//            val error = alloc<ObjCObjectVar<NSError?>>()
//            val attributes = manager.attributesOfItemAtPath(filePath, error.ptr) ?: return emptyMap()
//            val result = mutableMapOf<String, Any?>()
//            for ((key, value) in attributes) {
//                if (key != null && key is String) {
//                    result[key] = value
//                }
//            }
//            return result
//        }
//    }
//
//    val contentsDirectory: Path
//        get() = getDirPath(NSDocumentDirectory, true)
//
//    val cachesDirectory: Path
//        get() = getDirPath(NSCachesDirectory, true)
//
//    val temporaryDirectory: Path
//        get() = Path.fromUrlString(NSTemporaryDirectory())
//
//    @OptIn(ExperimentalForeignApi::class)
//    private fun fileExists(path: String, isDirectory: Boolean = false): Boolean {
//        memScoped {
//            val boolean = alloc<BooleanVar>()
//            boolean.value = isDirectory
//            return manager.fileExistsAtPath(path, isDirectory = boolean.ptr)
//        }
//    }
//
//    private fun ensureFileExists(path: String, create: Boolean = false, isDirectory: Boolean = false): Boolean {
//        val exists = fileExists(path, isDirectory)
//        if (!exists && !create) return false
//
//        if (!exists && create) {
//            return if (isDirectory) {
//                manager.createDirectoryAtPath(path, emptyMap<Any?, Any>())
//            } else {
//                manager.createFileAtPath(path, null, emptyMap<Any?, Any>())
//            }
//        }
//        return true
//    }
//
//    @OptIn(ExperimentalForeignApi::class)
//    private fun readDir(url: NSURL?): List<StatResult>? {
//        val stdPath = url?.standardizedURL?.path ?: return null
//        memScoped {
//            val error = alloc<ObjCObjectVar<NSError?>>()
//            val contents = manager.contentsOfDirectoryAtPath(stdPath, error.ptr) ?: return emptyList()
//            return contents.mapNotNull {
//                stat(url.URLByAppendingPathComponent(it as String) ?: return null)
//            }
//        }
//    }
//
//    fun readDir(path: String): List<StatResult>? = readDir(Path.urlFromString(path))
//    fun readDir(pathComponent: PathComponent): List<StatResult>? = readDir(pathComponent.url)
//
//
//    private fun stat(url: NSURL?): StatResult? {
//        val stdPath = url?.standardizedURL?.path ?: return null
//        val attributes = attributesOfFile(stdPath)
//        val createdAt = toInterval(attributes[NSFileCreationDate])
//        val modifiedAt = toInterval(attributes[NSFileModificationDate])
//        val size = attributes[NSFileSize] as? Double
//        val type = {
//            when (attributes[NSFileType] as? String) {
//                NSFileTypeRegular -> FileType.Regular
//                NSFileTypeDirectory -> FileType.Directory
//                else -> FileType.Unknown
//            }
//        }()
//
//        return StatResult(
//            name = url.lastPathComponent ?: "",
//            canonicalPath = PathComponent(stdPath),
//            absolutePath = PathComponent(stdPath),
//            createdAt = createdAt,
//            modifiedAt = modifiedAt,
//            size = size,
//            type = type)
//    }
//
//    fun stat(path: String): StatResult? = stat(Path.urlFromString(path))
//    fun stat(pathComponent: PathComponent): StatResult? = stat(pathComponent.url)
//
//
//    private fun readFile(url: NSURL?, encoding: ContentEncoding): String? {
//        val path = url?.standardizedURL?.path ?: return null
//        val data = manager.contentsAtPath(path) ?: return null
//        return String.fromData(data, encoding)
//
//    }
//
//    fun readFile(path: String, encoding: ContentEncoding): String? = readFile(Path.urlFromString(path), encoding)
//    fun readFile(pathComponent: PathComponent, encoding: ContentEncoding): String? = readFile(pathComponent.url, encoding)
//
//    fun readFile(path: String): ByteArray? {
//        val url = Path.urlFromString(path)
//        val pathFromUrl = url?.standardizedURL?.path ?: return null
//        val data = manager.contentsAtPath(pathFromUrl) ?: return null
//        return data.toByteArray()
//    }
//
//    fun readFile(pathComponent: PathComponent): ByteArray? {
//        val path = pathComponent.component ?: return null
//        return readFile(path)
//    }
//
//    private fun toInterval(input: Any?): Double? {
//        if (input == null || input !is NSDate) return null
//        return input.timeIntervalSince1970()
//    }
//
//    private fun writeFile(url: NSURL?, contents: String, create: Boolean, encoding: ContentEncoding): Boolean {
//        val path = url?.standardizedURL?.path ?: return false
//
//        if (!ensureFileExists(path, create, false))
//            return false
//
//        val data = contents.toData(encoding) ?: return false
//        return data.writeToFile(path, true)
//    }
//
//    fun writeFile(path: String, contents: String, create: Boolean, encoding: ContentEncoding): Boolean = writeFile(Path.urlFromString(path), contents, create, encoding)
//    fun writeFile(pathComponent: PathComponent, contents: String, create: Boolean, encoding: ContentEncoding): Boolean = writeFile(pathComponent.url, contents, create, encoding)
//
//    fun writeFile(path: String, contents: ByteArray, create: Boolean): Boolean {
//        val pathStandardized = Path.urlFromString(path)?.standardizedURL?.path ?: return false
//
//        if (!ensureFileExists(pathStandardized, create, false)) {
//            return false
//        }
//
//        val data = contents.toNSData() ?: return false
//        return data.writeToFile(pathStandardized, true)
//    }
//
//    fun writeFile(pathComponent: PathComponent, contents: ByteArray, create: Boolean): Boolean {
//        val path = pathComponent.component ?: return false
//        return writeFile(path, contents, create)
//    }
//
//    private fun appendFile(url: NSURL?, contents: String, create: Boolean, encoding: ContentEncoding): Boolean {
//        val path = url?.standardizedURL?.path ?: return false
//
//        if (encoding == ContentEncoding.Base64) {
//            val existingContents =  readFile(url, ContentEncoding.Base64) ?: ""
//            return writeFile(url, (existingContents + contents), create=create, encoding=ContentEncoding.Base64)
//        }
//
//        val data = contents.toData(encoding) ?: return false
//        if (!ensureFileExists(path, create, false)) return false
//
//        val handle = NSFileHandle.fileHandleForUpdatingAtPath(path) ?: return false
//        handle.seekToEndOfFile()
//        handle.writeData(data)
//        handle.closeFile()
//        return true
//    }
//
//    fun appendFile(path: String, contents: String, create: Boolean, encoding: ContentEncoding): Boolean = appendFile(Path.urlFromString(path), contents, create, encoding)
//    fun appendFile(pathComponent: PathComponent, contents: String, create: Boolean, encoding: ContentEncoding): Boolean = appendFile(pathComponent.url, contents, create, encoding)
//
//    private fun touch(url: NSURL?): Boolean {
//        val path = url?.standardizedURL?.path ?: return false
//        if (fileExists(path, false)) return false
//        return manager.createFileAtPath(path, null, null)
//    }
//
//    fun touch(path: String): Boolean = touch(Path.urlFromString(path))
//    fun touch(pathComponent: PathComponent): Boolean = touch(pathComponent.url)
//
//    private fun mkdir(url: NSURL?, recursive: Boolean): Boolean {
//
//        val path = url?.standardizedURL?.path ?: return false
//        if (ensureFileExists(path, create = false, isDirectory = true)) return false
//        memScoped {
//            val error = alloc<ObjCObjectVar<NSError?>>()
//            return manager.createDirectoryAtPath(path, recursive, emptyMap<Any?, Any>(), error.ptr)
//        }
//    }
//
//    fun mkdir(path: String, recursive: Boolean): Boolean = mkdir(Path.urlFromString(path), recursive)
//    fun mkdir(pathComponent: PathComponent, recursive: Boolean): Boolean = mkdir(pathComponent.url, recursive)
//
//    private fun exists(url: NSURL?): Boolean {
//        val path = url?.standardizedURL?.path ?: return false
//        return manager.fileExistsAtPath(path)
//    }
//
//    fun exists(path: String): Boolean = exists(Path.urlFromString(path))
//    fun exists(pathComponent: PathComponent): Boolean = exists(pathComponent.url)
//
//    private fun unlink(url: NSURL?): Boolean {
//        val path = url?.standardizedURL?.path ?: return false
//        memScoped {
//            val error = alloc<ObjCObjectVar<NSError?>>()
//            return manager.removeItemAtPath(path, error.ptr)
//        }
//    }
//
//    fun unlink(path: String): Boolean = unlink(Path.urlFromString(path))
//    fun unlink(pathComponent: PathComponent): Boolean = unlink(pathComponent.url)
//
//    private fun moveFile(srcUrl: NSURL?, destUrl: NSURL?): Boolean {
//        val srcPath = srcUrl?.standardizedURL?.path ?: return false
//        val destPath = destUrl?.standardizedURL?.path ?: return false
//        memScoped {
//            val error = alloc<ObjCObjectVar<NSError?>>()
//            return manager.moveItemAtPath(srcPath, destPath, error.ptr)
//        }
//    }
//
//    fun moveFile(srcPath: String, destPath: String): Boolean = moveFile(Path.urlFromString(srcPath), Path.urlFromString(destPath))
//    fun moveFile(srcPathComponent: PathComponent, destPathComponent: PathComponent): Boolean = moveFile(srcPathComponent.url, destPathComponent.url)
//
//
//    private fun copyFile(srcUrl: NSURL?, destUrl: NSURL?): Boolean {
//        val srcPath = srcUrl?.standardizedURL?.path ?: return false
//        val destPath = destUrl?.standardizedURL?.path ?: return false
//        memScoped {
//            val error = alloc<ObjCObjectVar<NSError?>>()
//            return manager.copyItemAtPath(srcPath, destPath, error.ptr)
//        }
//    }
//
//    fun copyFile(srcPath: String, destPath: String): Boolean = copyFile(Path.urlFromString(srcPath), Path.urlFromString(destPath))
//    fun copyFile(srcPathComponent: PathComponent, destPathComponent: PathComponent): Boolean = copyFile(srcPathComponent.url, destPathComponent.url)
//
//}